package org.sean.framework.bean;

import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.sean.framework.code.StatusInfo;
import org.sean.framework.util.ObjectUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * http响应通用结构类型
 *
 * @param <T> T
 * @author sean.xie
 */
@Data
public class BaseResult<T> {

    public static final int CODE_SUCCESS = 1000;
    public static final int CODE_ERROR = 0;

    /**
     * 状态,1000 代表成功(数据可用)
     */
    @Schema(description = "状态码")
    private int state = CODE_ERROR;
    /**
     * 错误消息
     */
    @Schema(description = "错误消息")
    private String message;
    /**
     * 错误详情
     */
    @Schema(description = "错误详情")
    private String exception;
    /**
     * 响应级别
     */
    @Schema(description = "响应级别")
    private Integer level;
    /**
     * 响应数据
     */
    @Schema(description = "响应数据")
    private T data;
    /**
     * 响应数据
     */
    @Schema(description = "响应数据", hidden = true)
    private List<T> list;

    public BaseResult() {
    }

    /**
     * 响应结构
     *
     * @param status  状态
     * @param message 错误消息
     */
    public BaseResult(Integer status, String message) {
        this(status, null, message);
    }

    /**
     * 响应结构
     *
     * @param status  状态
     * @param level   等级
     * @param message 错误消息
     */
    public BaseResult(Integer status, Integer level, String message) {
        this.state = status;
        this.message = message;
        this.level = level;
    }

    /**
     * 正确响应
     *
     * @param <T> T
     * @return 响应体
     */
    public static <T> BaseResult<T> success() {
        BaseResult<T> result = new BaseResult<>();
        result.setState(CODE_SUCCESS);
        return result;
    }

    /**
     * 正确响应
     *
     * @param <T>  T
     * @param data 响应数据
     * @return 响应体
     */
    public static <T> BaseResult<T> success(T data) {
        BaseResult<T> result = new BaseResult<>();
        result.setState(CODE_SUCCESS);
        result.setData(data);
        return result;
    }

    /**
     * 正确响应
     *
     * @param <T>  T
     * @param data 响应数据
     * @return 响应体
     */
    public static <T> BaseResult<PageData<T>> success(List<T> data) {
        BaseResult<PageData<T>> result = new BaseResult<>();
        result.setState(CODE_SUCCESS);
        result.setData(PageData.<T>builder().list(data).build());
        return result;
    }

    /**
     * 正确响应
     *
     * @param <T>  T
     * @param data 响应数据
     * @return 响应体
     */
    public static <T> BaseResult<T> successList(Collection<T> data) {
        BaseResult<T> result = new BaseResult<>();
        result.setState(CODE_SUCCESS);
        if (ObjectUtil.isEmpty(data)) {
            result.setList(Collections.emptyList());
        } else {
            result.setList(new ArrayList<>(data));
        }
        return result;
    }

    /**
     * 异常响应
     *
     * @param <T>     T
     * @param status  状态吗
     * @param message 错误信息
     * @return 响应体
     */
    public static <T> BaseResult<T> error(int status, String message) {
        BaseResult<T> result = new BaseResult<>();
        result.setState(status);
        result.setMessage(message);
        return result;
    }

    /**
     * 异常响应
     *
     * @param <T>        T
     * @param statusInfo 状态信息
     * @return 响应体
     */
    public static <T> BaseResult<T> error(StatusInfo statusInfo) {
        BaseResult<T> result = new BaseResult<>();
        result.setState(statusInfo.getCode());
        result.setLevel(statusInfo.getLevel());
        result.setMessage(statusInfo.getMessage());
        return result;
    }

    /**
     * 响应级别
     *
     * @return 响应级别
     */
    public Integer getLevel() {
        return level;
    }

    /**
     * 设置响应级别
     *
     * @param level 响应级别
     */
    public void setLevel(Integer level) {
        this.level = level;
    }

    /**
     * 响应数据
     *
     * @return 响应数据
     */
    public T getData() {
        return data;
    }

    /**
     * 设置响应数据
     *
     * @param data 响应数据
     */
    public void setData(T data) {
        this.data = data;
    }

    /**
     * 列表数据
     *
     * @return 列表数据
     */
    public List<T> getList() {
        return list;
    }

    /**
     * 设置列表数据
     *
     * @param list 数据
     */
    public void setList(List<T> list) {
        this.list = list;
    }

    /**
     * 错误消息
     *
     * @return 错误消息
     */
    public String getMessage() {
        return message;
    }

    /**
     * 设置提示消息
     *
     * @param message 错误消息
     */
    public void setMessage(String message) {
        this.message = message;
    }

    /**
     * @return 异常详情
     */
    public String getException() {
        return exception;
    }

    /**
     * 设置错误信息
     *
     * @param exception 异常信息
     */
    public void setException(String exception) {
        this.exception = exception;
    }

    /**
     * @return 是否成功
     */
    @Hidden
    public boolean isSuccess() {
        return (state == CODE_SUCCESS);
    }


}
